// Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
// Project developers.  See the top-level LICENSE file for dates and other
// details.  No copyright assignment is required to contribute to VisIt.

#include "QvisDataBinningWindow.h"

#include <DataBinningAttributes.h>

#include <QCheckBox>
#include <QComboBox>
#include <QGroupBox>
#include <QLabel>
#include <QLayout>
#include <QLineEdit>
#include <QButtonGroup>
#include <QRadioButton>
#include <QvisVariableButton.h>


// ****************************************************************************
// Method: QvisDataBinningWindow::QvisDataBinningWindow
//
// Purpose: 
//   Constructor
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

QvisDataBinningWindow::QvisDataBinningWindow(const int type,
                         DataBinningAttributes *subj,
                         const QString &caption,
                         const QString &shortName,
                         QvisNotepadArea *notepad)
    : QvisOperatorWindow(type,subj, caption, shortName, notepad)
{
    atts = subj;
}


// ****************************************************************************
// Method: QvisDataBinningWindow::~QvisDataBinningWindow
//
// Purpose: 
//   Destructor
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

QvisDataBinningWindow::~QvisDataBinningWindow()
{
}


// ****************************************************************************
// Method: QvisDataBinningWindow::CreateWindowContents
//
// Purpose: 
//   Creates the widgets for the window.
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   
//   Hank Childs, Sun Jul 31 16:01:41 PDT 2011
//   Add support for bins based on spatial dimensions.
//
//   Hank Childs, Mon Jul 16 17:13:53 PDT 2012
//   Add support for outputs on the mesh or the bins.
//
//   Hank Childs, Fri Jan  4 11:49:36 PST 2013
//   Remove unused bins for curves.
//
//   Kathleen Biagas, Tue Apr 18 16:34:41 PDT 2023
//   Support Qt6: buttonClicked -> idClicked.
//
// ****************************************************************************

void
QvisDataBinningWindow::CreateWindowContents()
{
    QGridLayout *mainLayout = new QGridLayout(0);
    topLayout->addLayout(mainLayout);

    QGroupBox *bdGroup = new QGroupBox(central);
    bdGroup->setTitle(tr("Bin Definitions"));
    mainLayout->addWidget(bdGroup);

    QGridLayout *bdLayout = new QGridLayout(bdGroup);

    numDimensionsLabel = new QLabel(tr("Dimensions"), central);
    bdLayout->addWidget(numDimensionsLabel,0,0);
    numDimensions = new QWidget(central);
    numDimensionsCombo = new QComboBox(numDimensions);
    numDimensionsCombo->addItem("1D");
    numDimensionsCombo->addItem("2D");
    numDimensionsCombo->addItem("3D");
    connect(numDimensionsCombo, SIGNAL(activated(int)),
            this, SLOT(numDimensionsChanged(int)));
    bdLayout->addWidget(numDimensionsCombo, 0,1);

    QTabWidget *dimTabs = new QTabWidget(central);
    QWidget *dim1Tab = new QWidget(central);
    QWidget *dim2Tab = new QWidget(central);
    QWidget *dim3Tab = new QWidget(central);
    dimTabs->addTab(dim1Tab, tr("Dimension 1"));
    dimTabs->addTab(dim2Tab, tr("Dimension 2"));
    dimTabs->addTab(dim3Tab, tr("Dimension 3"));
    bdLayout->addWidget(dimTabs, 1,0, 1, 3);
    QGridLayout *dim1Layout = new QGridLayout(dim1Tab);
    QGridLayout *dim2Layout = new QGridLayout(dim2Tab);
    QGridLayout *dim3Layout = new QGridLayout(dim3Tab);

    dim1BinBasedOn = new QLabel(tr("Bin based on"), central);
    dim1Layout->addWidget(dim1BinBasedOn,0,0);

    QWidget *dim1BinBasedOnWidget = new QWidget(central);
    dim1BinBasedOnButtonGroup = new QButtonGroup(dim1BinBasedOnWidget);
    dim1VarLabel = new QRadioButton(tr("Variable"), dim1BinBasedOnWidget);
    dim1Layout->addWidget(dim1VarLabel,0,1, Qt::AlignRight);
    int dim1VarMask = QvisVariableButton::Scalars;
    dim1Var = new QvisVariableButton(true, true, true, dim1VarMask, central);
    connect(dim1Var, SIGNAL(activated(const QString&)),
            this, SLOT(dim1VarChanged(const QString&)));
    dim1Layout->addWidget(dim1Var, 0,2);
    dim1XLabel = new QRadioButton(tr("X"), dim1BinBasedOnWidget);
    dim1Layout->addWidget(dim1XLabel, 0,3);
    dim1YLabel = new QRadioButton(tr("Y"), dim1BinBasedOnWidget);
    dim1Layout->addWidget(dim1YLabel, 0,4);
    dim1ZLabel = new QRadioButton(tr("Z"), dim1BinBasedOnWidget);
    dim1Layout->addWidget(dim1ZLabel, 0,5);
    dim1BinBasedOnButtonGroup->addButton(dim1VarLabel,0);
    dim1BinBasedOnButtonGroup->addButton(dim1XLabel,1);
    dim1BinBasedOnButtonGroup->addButton(dim1YLabel,2);
    dim1BinBasedOnButtonGroup->addButton(dim1ZLabel,3);
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
    connect(dim1BinBasedOnButtonGroup, SIGNAL(buttonClicked(int)),
            this, SLOT(dim1BinBasedOnChanged(int)));
#else
    connect(dim1BinBasedOnButtonGroup, SIGNAL(idClicked(int)),
            this, SLOT(dim1BinBasedOnChanged(int)));
#endif

    dim1NumBinsLabel = new QLabel(tr("Number of bins"), central);
    dim1Layout->addWidget(dim1NumBinsLabel,1,0);
    dim1NumBins = new QLineEdit(central);
    connect(dim1NumBins, SIGNAL(returnPressed()),
            this, SLOT(dim1NumBinsProcessText()));
    dim1Layout->addWidget(dim1NumBins, 1,1);

    dim1SpecifyRange = new QCheckBox(tr("Specify range"), central);
    dim1Layout->addWidget(dim1SpecifyRange, 2, 0);
    connect(dim1SpecifyRange, SIGNAL(toggled(bool)),
            this, SLOT(dim1SpecifyRangeToggled(bool)));

    dim1MinRangeLabel = new QLabel(tr("Min"), central);
    dim1Layout->addWidget(dim1MinRangeLabel,3,0);
    dim1MinRange = new QLineEdit(central);
    connect(dim1MinRange, SIGNAL(returnPressed()),
            this, SLOT(dim1MinRangeProcessText()));
    dim1Layout->addWidget(dim1MinRange, 3,1);

    dim1MaxRangeLabel = new QLabel(tr("Max"), central);
    dim1Layout->addWidget(dim1MaxRangeLabel,4,0);
    dim1MaxRange = new QLineEdit(central);
    connect(dim1MaxRange, SIGNAL(returnPressed()),
            this, SLOT(dim1MaxRangeProcessText()));
    dim1Layout->addWidget(dim1MaxRange, 4,1);

    dim2BinBasedOn = new QLabel(tr("Bin based on"), central);
    dim2Layout->addWidget(dim2BinBasedOn,0,0);

    QWidget *dim2BinBasedOnWidget = new QWidget(central);
    dim2BinBasedOnButtonGroup = new QButtonGroup(dim2BinBasedOnWidget);
    dim2VarLabel = new QRadioButton(tr("Variable"), dim2BinBasedOnWidget);
    dim2Layout->addWidget(dim2VarLabel,0,1, Qt::AlignRight);
    int dim2VarMask = QvisVariableButton::Scalars;
    dim2Var = new QvisVariableButton(true, true, true, dim2VarMask, central);
    connect(dim2Var, SIGNAL(activated(const QString&)),
            this, SLOT(dim2VarChanged(const QString&)));
    dim2Layout->addWidget(dim2Var, 0,2);
    dim2XLabel = new QRadioButton(tr("X"), dim2BinBasedOnWidget);
    dim2Layout->addWidget(dim2XLabel, 0,3);
    dim2YLabel = new QRadioButton(tr("Y"), dim2BinBasedOnWidget);
    dim2Layout->addWidget(dim2YLabel, 0,4);
    dim2ZLabel = new QRadioButton(tr("Z"), dim2BinBasedOnWidget);
    dim2Layout->addWidget(dim2ZLabel, 0,5);

    dim2NumBinsLabel = new QLabel(tr("Number of bins"), central);
    dim2Layout->addWidget(dim2NumBinsLabel,1,0);
    dim2NumBins = new QLineEdit(central);
    connect(dim2NumBins, SIGNAL(returnPressed()),
            this, SLOT(dim2NumBinsProcessText()));
    dim2Layout->addWidget(dim2NumBins, 1,1);

    dim2SpecifyRange = new QCheckBox(tr("Specify range"), central);
    dim2Layout->addWidget(dim2SpecifyRange, 2, 0);
    connect(dim2SpecifyRange, SIGNAL(toggled(bool)),
            this, SLOT(dim2SpecifyRangeToggled(bool)));

    dim2MinRangeLabel = new QLabel(tr("Min"), central);
    dim2Layout->addWidget(dim2MinRangeLabel,3,0);
    dim2MinRange = new QLineEdit(central);
    connect(dim2MinRange, SIGNAL(returnPressed()),
            this, SLOT(dim2MinRangeProcessText()));
    dim2Layout->addWidget(dim2MinRange, 3,1);

    dim2MaxRangeLabel = new QLabel(tr("Max"), central);
    dim2Layout->addWidget(dim2MaxRangeLabel,4,0);
    dim2MaxRange = new QLineEdit(central);
    connect(dim2MaxRange, SIGNAL(returnPressed()),
            this, SLOT(dim2MaxRangeProcessText()));
    dim2Layout->addWidget(dim2MaxRange, 4,1);
    dim2BinBasedOnButtonGroup->addButton(dim2VarLabel,0);
    dim2BinBasedOnButtonGroup->addButton(dim2XLabel,1);
    dim2BinBasedOnButtonGroup->addButton(dim2YLabel,2);
    dim2BinBasedOnButtonGroup->addButton(dim2ZLabel,3);
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
    connect(dim2BinBasedOnButtonGroup, SIGNAL(buttonClicked(int)),
            this, SLOT(dim2BinBasedOnChanged(int)));
#else
    connect(dim2BinBasedOnButtonGroup, SIGNAL(idClicked(int)),
            this, SLOT(dim2BinBasedOnChanged(int)));
#endif

    dim3BinBasedOn = new QLabel(tr("Bin based on"), central);
    dim3Layout->addWidget(dim3BinBasedOn,0,0);

    QWidget *dim3BinBasedOnWidget = new QWidget(central);
    dim3BinBasedOnButtonGroup = new QButtonGroup(dim3BinBasedOnWidget);
    dim3VarLabel = new QRadioButton(tr("Variable"), dim3BinBasedOnWidget);
    dim3Layout->addWidget(dim3VarLabel,0,1, Qt::AlignRight);
    int dim3VarMask = QvisVariableButton::Scalars;
    dim3Var = new QvisVariableButton(true, true, true, dim3VarMask, central);
    connect(dim3Var, SIGNAL(activated(const QString&)),
            this, SLOT(dim3VarChanged(const QString&)));
    dim3Layout->addWidget(dim3Var, 0,2);
    dim3XLabel = new QRadioButton(tr("X"), dim3BinBasedOnWidget);
    dim3Layout->addWidget(dim3XLabel, 0,3);
    dim3YLabel = new QRadioButton(tr("Y"), dim3BinBasedOnWidget);
    dim3Layout->addWidget(dim3YLabel, 0,4);
    dim3ZLabel = new QRadioButton(tr("Z"), dim3BinBasedOnWidget);
    dim3Layout->addWidget(dim3ZLabel, 0,5);

    dim3NumBinsLabel = new QLabel(tr("Number of bins"), central);
    dim3Layout->addWidget(dim3NumBinsLabel,1,0);
    dim3NumBins = new QLineEdit(central);
    connect(dim3NumBins, SIGNAL(returnPressed()),
            this, SLOT(dim3NumBinsProcessText()));
    dim3Layout->addWidget(dim3NumBins, 1,1);

    dim3SpecifyRange = new QCheckBox(tr("Specify range"), central);
    dim3Layout->addWidget(dim3SpecifyRange, 2, 0);
    connect(dim3SpecifyRange, SIGNAL(toggled(bool)),
            this, SLOT(dim3SpecifyRangeToggled(bool)));

    dim3MinRangeLabel = new QLabel(tr("Min"), central);
    dim3Layout->addWidget(dim3MinRangeLabel,3,0);
    dim3MinRange = new QLineEdit(central);
    connect(dim3MinRange, SIGNAL(returnPressed()),
            this, SLOT(dim3MinRangeProcessText()));
    dim3Layout->addWidget(dim3MinRange, 3,1);

    dim3MaxRangeLabel = new QLabel(tr("Max"), central);
    dim3Layout->addWidget(dim3MaxRangeLabel,4,0);
    dim3MaxRange = new QLineEdit(central);
    connect(dim3MaxRange, SIGNAL(returnPressed()),
            this, SLOT(dim3MaxRangeProcessText()));
    dim3Layout->addWidget(dim3MaxRange, 4,1);
    dim3BinBasedOnButtonGroup->addButton(dim3VarLabel,0);
    dim3BinBasedOnButtonGroup->addButton(dim3XLabel,1);
    dim3BinBasedOnButtonGroup->addButton(dim3YLabel,2);
    dim3BinBasedOnButtonGroup->addButton(dim3ZLabel,3);
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
    connect(dim3BinBasedOnButtonGroup, SIGNAL(buttonClicked(int)),
            this, SLOT(dim3BinBasedOnChanged(int)));
#else
    connect(dim3BinBasedOnButtonGroup, SIGNAL(idClicked(int)),
            this, SLOT(dim3BinBasedOnChanged(int)));
#endif

    outOfBoundsBehaviorLabel = new QLabel(tr("Behavior for data outside range"), central);
    bdLayout->addWidget(outOfBoundsBehaviorLabel,2,0);
    outOfBoundsBehavior = new QWidget(central);
    outOfBoundsBehaviorButtonGroup= new QButtonGroup(outOfBoundsBehavior);
    QHBoxLayout *outOfBoundsBehaviorLayout = new QHBoxLayout(outOfBoundsBehavior);
    outOfBoundsBehaviorLayout->setContentsMargins(0,0,0,0);
    outOfBoundsBehaviorLayout->setSpacing(10);
    QRadioButton *outOfBoundsBehaviorOutOfBoundsBehaviorClamp = new QRadioButton(tr("Clamp"), outOfBoundsBehavior);
    outOfBoundsBehaviorButtonGroup->addButton(outOfBoundsBehaviorOutOfBoundsBehaviorClamp,0);
    outOfBoundsBehaviorLayout->addWidget(outOfBoundsBehaviorOutOfBoundsBehaviorClamp);
    QRadioButton *outOfBoundsBehaviorOutOfBoundsBehaviorDiscard = new QRadioButton(tr("Discard"), outOfBoundsBehavior);
    outOfBoundsBehaviorButtonGroup->addButton(outOfBoundsBehaviorOutOfBoundsBehaviorDiscard,1);
    outOfBoundsBehaviorLayout->addWidget(outOfBoundsBehaviorOutOfBoundsBehaviorDiscard);
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
    connect(outOfBoundsBehaviorButtonGroup, SIGNAL(buttonClicked(int)),
            this, SLOT(outOfBoundsBehaviorChanged(int)));
#else
    connect(outOfBoundsBehaviorButtonGroup, SIGNAL(idClicked(int)),
            this, SLOT(outOfBoundsBehaviorChanged(int)));
#endif
    bdLayout->addWidget(outOfBoundsBehavior, 2,1);

    QGroupBox *rtGroup = new QGroupBox(central);
    rtGroup->setTitle(tr("Reduction"));
    mainLayout->addWidget(rtGroup);

    QGridLayout *rtLayout = new QGridLayout(rtGroup);

    reductionOperatorLabel = new QLabel(tr("Reduction Operator"), central);
    rtLayout->addWidget(reductionOperatorLabel,0,0);
    reductionOperator = new QWidget(central);
    reductionCombo = new QComboBox(reductionOperator);
    reductionCombo->addItem("Average");
    reductionCombo->addItem("Minimum");
    reductionCombo->addItem("Maximum");
    reductionCombo->addItem("Standard Deviation");
    reductionCombo->addItem("Variance");
    reductionCombo->addItem("Sum");
    reductionCombo->addItem("Count");
    reductionCombo->addItem("RMS");
    reductionCombo->addItem("PDF");
    connect(reductionCombo, SIGNAL(activated(int)),
            this, SLOT(reductionOperatorClicked(int)));
    rtLayout->addWidget(reductionCombo, 0, 1);

    varForReductionLabel = new QLabel(tr("Variable"), central);
    rtLayout->addWidget(varForReductionLabel,1,0);
    int varForReductionMask = QvisVariableButton::Scalars;
    varForReduction = new QvisVariableButton(true, true, true, varForReductionMask, central);
    connect(varForReduction, SIGNAL(activated(const QString&)),
            this, SLOT(varForReductionChanged(const QString&)));
    rtLayout->addWidget(varForReduction, 1,1);

    emptyValLabel = new QLabel(tr("Value for bins with no data"), central);
    rtLayout->addWidget(emptyValLabel,2,0);
    emptyVal = new QLineEdit(central);
    connect(emptyVal, SIGNAL(returnPressed()),
            this, SLOT(emptyValProcessText()));
    rtLayout->addWidget(emptyVal, 2,1);

    removeEmptyBins = new QCheckBox(tr("Remove bins with no data (curves only)"), central);
    rtLayout->addWidget(removeEmptyBins, 3, 0);
    connect(removeEmptyBins, SIGNAL(toggled(bool)),
            this, SLOT(removeEmptyBinsToggled(bool)));

    QGroupBox *outputGroup = new QGroupBox(central);
    outputGroup->setTitle(tr("Output"));
    mainLayout->addWidget(outputGroup);

    QGridLayout *outputLayout = new QGridLayout(outputGroup);

    QLabel *outputLabel = new QLabel(tr("Output on"), central);
    outputLayout->addWidget(outputLabel,0,0);
    QWidget *outputWidget = new QWidget(central);
    outputButtonGroup= new QButtonGroup(outputWidget);
    QHBoxLayout *outputHLayout = new QHBoxLayout(outputWidget);
    outputHLayout->setContentsMargins(0,0,0,0);
    outputHLayout->setSpacing(0);
    QRadioButton *outputBins = new QRadioButton(tr("Bins"), outputWidget);
    outputButtonGroup->addButton(outputBins,0);
    outputHLayout->addWidget(outputBins);
    QRadioButton *outputMesh = new QRadioButton(tr("Mesh"), outputWidget);
    outputButtonGroup->addButton(outputMesh,1);
    outputHLayout->addWidget(outputMesh);
    outputLayout->addWidget(outputWidget, 0, 1);
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
    connect(outputButtonGroup, SIGNAL(buttonClicked(int)),
            this, SLOT(outputChanged(int)));
#else
    connect(outputButtonGroup, SIGNAL(idClicked(int)),
            this, SLOT(outputChanged(int)));
#endif
}


// ****************************************************************************
// Method: QvisDataBinningWindow::UpdateWindow
//
// Purpose: 
//   Updates the widgets in the window when the subject changes.
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   
//   Hank Childs, Sun Jul 31 16:01:41 PDT 2011
//   Add support for bins based on spatial dimensions.
//
//   Hank Childs, Mon Jul 16 17:13:53 PDT 2012
//   Add support for outputs on the mesh or the bins.
//
//   Hank Childs, Fri Jan  4 11:49:36 PST 2013
//   Remove unused bins for curves.
//
//   Kathleen Biagas, Tue May 4 2021
//   Ensure dim2Var is enabled when NumDimensions is 3.
//
// ****************************************************************************

void
QvisDataBinningWindow::UpdateWindow(bool doAll)
{
    for(int i = 0; i < atts->NumAttributes(); ++i)
    {
        if(!doAll)
        {
            if(!atts->IsSelected(i))
            {
                continue;
            }
        }

        switch(i)
        {
          case DataBinningAttributes::ID_dim1SpecifyRange:
            if (atts->GetDim1SpecifyRange())
            {
                dim1MinRange->setEnabled(true);
                if(dim1MinRangeLabel)
                    dim1MinRangeLabel->setEnabled(true);
                dim1MaxRange->setEnabled(true);
                if(dim1MaxRangeLabel)
                    dim1MaxRangeLabel->setEnabled(true);
            }
            else
            {
                dim1MinRange->setEnabled(false);
                if(dim1MinRangeLabel)
                    dim1MinRangeLabel->setEnabled(false);
                dim1MaxRange->setEnabled(false);
                if(dim1MaxRangeLabel)
                    dim1MaxRangeLabel->setEnabled(false);
            }
            break;
          case DataBinningAttributes::ID_dim2SpecifyRange:
            if ((atts->GetNumDimensions() == DataBinningAttributes::Two || atts->GetNumDimensions() == DataBinningAttributes::Three) && atts->GetDim2SpecifyRange())
            {
                dim2MinRange->setEnabled(true);
                if(dim2MinRangeLabel)
                    dim2MinRangeLabel->setEnabled(true);
                dim2MaxRange->setEnabled(true);
                if(dim2MaxRangeLabel)
                    dim2MaxRangeLabel->setEnabled(true);
            }
            else
            {
                dim2MinRange->setEnabled(false);
                if(dim2MinRangeLabel)
                    dim2MinRangeLabel->setEnabled(false);
                dim2MaxRange->setEnabled(false);
                if(dim2MaxRangeLabel)
                    dim2MaxRangeLabel->setEnabled(false);
            }
            break;
          case DataBinningAttributes::ID_dim3SpecifyRange:
            if (atts->GetNumDimensions() == DataBinningAttributes::Three && atts->GetDim3SpecifyRange())
            {
                dim3MinRange->setEnabled(true);
                if(dim3MinRangeLabel)
                    dim3MinRangeLabel->setEnabled(true);
                dim3MaxRange->setEnabled(true);
                if(dim3MaxRangeLabel)
                    dim3MaxRangeLabel->setEnabled(true);
            }
            else
            {
                dim3MinRange->setEnabled(false);
                if(dim3MinRangeLabel)
                    dim3MinRangeLabel->setEnabled(false);
                dim3MaxRange->setEnabled(false);
                if(dim3MaxRangeLabel)
                    dim3MaxRangeLabel->setEnabled(false);
            }
            break;
          case DataBinningAttributes::ID_numDimensions:
            if (atts->GetNumDimensions() == DataBinningAttributes::Two || atts->GetNumDimensions() == DataBinningAttributes::Three)
            {
                dim2BinBasedOn->setEnabled(true);
                if (atts->GetDim2BinBasedOn() == DataBinningAttributes::Variable)
                   dim2Var->setEnabled(true);
                dim2VarLabel->setEnabled(true);
                dim2XLabel->setEnabled(true);
                dim2YLabel->setEnabled(true);
                dim2ZLabel->setEnabled(true);
            }
            else
            {
                dim2BinBasedOn->setEnabled(false);
                dim2Var->setEnabled(false);
                dim2VarLabel->setEnabled(false);
                dim2XLabel->setEnabled(false);
                dim2YLabel->setEnabled(false);
                dim2ZLabel->setEnabled(false);
            }
            if (atts->GetNumDimensions() == DataBinningAttributes::Two || atts->GetNumDimensions() == DataBinningAttributes::Three)
                dim2SpecifyRange->setEnabled(true);
            else
                dim2SpecifyRange->setEnabled(false);
            if ((atts->GetNumDimensions() == DataBinningAttributes::Two || atts->GetNumDimensions() == DataBinningAttributes::Three) && atts->GetDim2SpecifyRange())
            {
                dim2MinRange->setEnabled(true);
                if(dim2MinRangeLabel)
                    dim2MinRangeLabel->setEnabled(true);
            }
            else
            {
                dim2MinRange->setEnabled(false);
                if(dim2MinRangeLabel)
                    dim2MinRangeLabel->setEnabled(false);
            }
            if ((atts->GetNumDimensions() == DataBinningAttributes::Two || atts->GetNumDimensions() == DataBinningAttributes::Three) && atts->GetDim2SpecifyRange())
            {
                dim2MaxRange->setEnabled(true);
                if(dim2MaxRangeLabel)
                    dim2MaxRangeLabel->setEnabled(true);
            }
            else
            {
                dim2MaxRange->setEnabled(false);
                if(dim2MaxRangeLabel)
                    dim2MaxRangeLabel->setEnabled(false);
            }
            if (atts->GetNumDimensions() == DataBinningAttributes::Two || atts->GetNumDimensions() == DataBinningAttributes::Three)
            {
                dim2NumBins->setEnabled(true);
                if(dim2NumBinsLabel)
                    dim2NumBinsLabel->setEnabled(true);
            }
            else
            {
                dim2NumBins->setEnabled(false);
                if(dim2NumBinsLabel)
                    dim2NumBinsLabel->setEnabled(false);
            }
            if (atts->GetNumDimensions() == DataBinningAttributes::Three)
            {
                dim3BinBasedOn->setEnabled(true);
                if (atts->GetDim3BinBasedOn() == DataBinningAttributes::Variable)
                    dim3Var->setEnabled(true);
                dim3VarLabel->setEnabled(true);
                dim3XLabel->setEnabled(true);
                dim3YLabel->setEnabled(true);
                dim3ZLabel->setEnabled(true);
            }
            else
            {
                dim3BinBasedOn->setEnabled(false);
                dim3Var->setEnabled(false);
                dim3VarLabel->setEnabled(false);
                dim3XLabel->setEnabled(false);
                dim3YLabel->setEnabled(false);
                dim3ZLabel->setEnabled(false);
            }
            if (atts->GetNumDimensions() == DataBinningAttributes::Three)
                dim3SpecifyRange->setEnabled(true);
            else
                dim3SpecifyRange->setEnabled(false);
            if (atts->GetNumDimensions() == DataBinningAttributes::Three && atts->GetDim3SpecifyRange())
            {
                dim3MinRange->setEnabled(true);
                if(dim3MinRangeLabel)
                    dim3MinRangeLabel->setEnabled(true);
            }
            else
            {
                dim3MinRange->setEnabled(false);
                if(dim3MinRangeLabel)
                    dim3MinRangeLabel->setEnabled(false);
            }
            if (atts->GetNumDimensions() == DataBinningAttributes::Three && atts->GetDim3SpecifyRange())
            {
                dim3MaxRange->setEnabled(true);
                if(dim3MaxRangeLabel)
                    dim3MaxRangeLabel->setEnabled(true);
            }
            else
            {
                dim3MaxRange->setEnabled(false);
                if(dim3MaxRangeLabel)
                    dim3MaxRangeLabel->setEnabled(false);
            }
            if (atts->GetNumDimensions() == DataBinningAttributes::Three)
            {
                dim3NumBins->setEnabled(true);
                if(dim3NumBinsLabel)
                    dim3NumBinsLabel->setEnabled(true);
            }
            else
            {
                dim3NumBins->setEnabled(false);
                if(dim3NumBinsLabel)
                    dim3NumBinsLabel->setEnabled(false);
            }
            numDimensionsCombo->blockSignals(true);
            numDimensionsCombo->setCurrentIndex((int)atts->GetNumDimensions());
            numDimensionsCombo->blockSignals(false);
            break;
          case DataBinningAttributes::ID_dim1Var:
            dim1Var->blockSignals(true);
            dim1Var->setText(QString(atts->GetDim1Var().c_str()));
            dim1Var->blockSignals(false);
            break;
          case DataBinningAttributes::ID_dim1MinRange:
            dim1MinRange->setText(DoubleToQString(atts->GetDim1MinRange()));
            break;
          case DataBinningAttributes::ID_dim1MaxRange:
            dim1MaxRange->setText(DoubleToQString(atts->GetDim1MaxRange()));
            break;
          case DataBinningAttributes::ID_dim1NumBins:
            dim1NumBins->setText(IntToQString(atts->GetDim1NumBins()));
            break;
          case DataBinningAttributes::ID_dim2Var:
            dim2Var->blockSignals(true);
            dim2Var->setText(QString(atts->GetDim2Var().c_str()));
            dim2Var->blockSignals(false);
            break;
          case DataBinningAttributes::ID_dim2MinRange:
            dim2MinRange->setText(DoubleToQString(atts->GetDim2MinRange()));
            break;
          case DataBinningAttributes::ID_dim2MaxRange:
            dim2MaxRange->setText(DoubleToQString(atts->GetDim2MaxRange()));
            break;
          case DataBinningAttributes::ID_dim2NumBins:
            dim2NumBins->setText(IntToQString(atts->GetDim2NumBins()));
            break;
          case DataBinningAttributes::ID_dim3Var:
            dim3Var->blockSignals(true);
            dim3Var->setText(QString(atts->GetDim3Var().c_str()));
            dim3Var->blockSignals(false);
            break;
          case DataBinningAttributes::ID_dim3MinRange:
            dim3MinRange->setText(DoubleToQString(atts->GetDim3MinRange()));
            break;
          case DataBinningAttributes::ID_dim3MaxRange:
            dim3MaxRange->setText(DoubleToQString(atts->GetDim3MaxRange()));
            break;
          case DataBinningAttributes::ID_dim3NumBins:
            dim3NumBins->setText(IntToQString(atts->GetDim3NumBins()));
            break;
          case DataBinningAttributes::ID_outOfBoundsBehavior:
            outOfBoundsBehaviorButtonGroup->blockSignals(true);
            if(outOfBoundsBehaviorButtonGroup->button((int)atts->GetOutOfBoundsBehavior()) != 0)
                outOfBoundsBehaviorButtonGroup->button((int)atts->GetOutOfBoundsBehavior())->setChecked(true);
            outOfBoundsBehaviorButtonGroup->blockSignals(false);
            break;
          case DataBinningAttributes::ID_reductionOperator:
            if (atts->GetReductionOperator() == DataBinningAttributes::Average || atts->GetReductionOperator() == DataBinningAttributes::Minimum || atts->GetReductionOperator() == DataBinningAttributes::Maximum || atts->GetReductionOperator() == DataBinningAttributes::StandardDeviation || atts->GetReductionOperator() == DataBinningAttributes::Variance || atts->GetReductionOperator() == DataBinningAttributes::Sum)
            {
                varForReduction->setEnabled(true);
                if(varForReductionLabel)
                    varForReductionLabel->setEnabled(true);
            }
            else
            {
                varForReduction->setEnabled(false);
                if(varForReductionLabel)
                    varForReductionLabel->setEnabled(false);
            }
            reductionCombo->blockSignals(true);
            reductionCombo->setCurrentIndex(atts->GetReductionOperator());
            reductionCombo->blockSignals(false);
            break;
          case DataBinningAttributes::ID_varForReduction:
            varForReduction->blockSignals(true);
            varForReduction->setText(QString(atts->GetVarForReduction().c_str()));
            varForReduction->blockSignals(false);
            break;
          case DataBinningAttributes::ID_emptyVal:
            emptyVal->setText(DoubleToQString(atts->GetEmptyVal()));
            break;
          case DataBinningAttributes::ID_removeEmptyValFromCurve:
            removeEmptyBins->setChecked(atts->GetRemoveEmptyValFromCurve());
            break;
          case DataBinningAttributes::ID_dim1BinBasedOn:
            if (atts->GetDim1BinBasedOn() == DataBinningAttributes::Variable)
               dim1Var->setEnabled(true);
            else
               dim1Var->setEnabled(false);
            if (atts->GetDim1BinBasedOn() == DataBinningAttributes::Variable)
               dim1VarLabel->setChecked(true);
            else if (atts->GetDim1BinBasedOn() == DataBinningAttributes::X)
               dim1XLabel->setChecked(true);
            else if (atts->GetDim1BinBasedOn() == DataBinningAttributes::Y)
               dim1YLabel->setChecked(true);
            else if (atts->GetDim1BinBasedOn() == DataBinningAttributes::Z)
               dim1ZLabel->setChecked(true);
            break;
          case DataBinningAttributes::ID_dim2BinBasedOn:
            if (atts->GetDim2BinBasedOn() == DataBinningAttributes::Variable
                && (atts->GetNumDimensions() == DataBinningAttributes::Two ||
                    atts->GetNumDimensions() == DataBinningAttributes::Three))
               dim2Var->setEnabled(true);
            else
               dim2Var->setEnabled(false);
            if (atts->GetDim2BinBasedOn() == DataBinningAttributes::Variable)
               dim2VarLabel->setChecked(true);
            else if (atts->GetDim2BinBasedOn() == DataBinningAttributes::X)
               dim2XLabel->setChecked(true);
            else if (atts->GetDim2BinBasedOn() == DataBinningAttributes::Y)
               dim2YLabel->setChecked(true);
            else if (atts->GetDim2BinBasedOn() == DataBinningAttributes::Z)
               dim2ZLabel->setChecked(true);
            break;
          case DataBinningAttributes::ID_dim3BinBasedOn:
            if (atts->GetDim3BinBasedOn() == DataBinningAttributes::Variable
                && atts->GetNumDimensions() == DataBinningAttributes::Three)
               dim3Var->setEnabled(true);
            else
               dim3Var->setEnabled(false);
            if (atts->GetDim3BinBasedOn() == DataBinningAttributes::Variable)
               dim3VarLabel->setChecked(true);
            else if (atts->GetDim3BinBasedOn() == DataBinningAttributes::X)
               dim3XLabel->setChecked(true);
            else if (atts->GetDim3BinBasedOn() == DataBinningAttributes::Y)
               dim3YLabel->setChecked(true);
            else if (atts->GetDim3BinBasedOn() == DataBinningAttributes::Z)
               dim3ZLabel->setChecked(true);
            break;
          case DataBinningAttributes::ID_outputType:
            outputButtonGroup->blockSignals(true);
            if(outputButtonGroup->button((int)atts->GetOutputType()) != 0)
                outputButtonGroup->button((int)atts->GetOutputType())->setChecked(true);
            outputButtonGroup->blockSignals(false);
            break;
        }
    }
}


// ****************************************************************************
// Method: QvisDataBinningWindow::GetCurrentValues
//
// Purpose: 
//   Gets values from certain widgets and stores them in the subject.
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

void
QvisDataBinningWindow::GetCurrentValues(int which_widget)
{
    bool doAll = (which_widget == -1);

    // Do dim1MinRange
    if(which_widget == DataBinningAttributes::ID_dim1MinRange || doAll)
    {
        double val;
        if(LineEditGetDouble(dim1MinRange, val))
            atts->SetDim1MinRange(val);
        else
        {
            ResettingError(tr("Min"),
                DoubleToQString(atts->GetDim1MinRange()));
            atts->SetDim1MinRange(atts->GetDim1MinRange());
        }
    }

    // Do dim1MaxRange
    if(which_widget == DataBinningAttributes::ID_dim1MaxRange || doAll)
    {
        double val;
        if(LineEditGetDouble(dim1MaxRange, val))
            atts->SetDim1MaxRange(val);
        else
        {
            ResettingError(tr("Max"),
                DoubleToQString(atts->GetDim1MaxRange()));
            atts->SetDim1MaxRange(atts->GetDim1MaxRange());
        }
    }

    // Do dim1NumBins
    if(which_widget == DataBinningAttributes::ID_dim1NumBins || doAll)
    {
        int val;
        if(LineEditGetInt(dim1NumBins, val))
            atts->SetDim1NumBins(val);
        else
        {
            ResettingError(tr("NumBins"),
                IntToQString(atts->GetDim1NumBins()));
            atts->SetDim1NumBins(atts->GetDim1NumBins());
        }
    }

    // Do dim2MinRange
    if(which_widget == DataBinningAttributes::ID_dim2MinRange || doAll)
    {
        double val;
        if(LineEditGetDouble(dim2MinRange, val))
            atts->SetDim2MinRange(val);
        else
        {
            ResettingError(tr("Min"),
                DoubleToQString(atts->GetDim2MinRange()));
            atts->SetDim2MinRange(atts->GetDim2MinRange());
        }
    }

    // Do dim2MaxRange
    if(which_widget == DataBinningAttributes::ID_dim2MaxRange || doAll)
    {
        double val;
        if(LineEditGetDouble(dim2MaxRange, val))
            atts->SetDim2MaxRange(val);
        else
        {
            ResettingError(tr("Max"),
                DoubleToQString(atts->GetDim2MaxRange()));
            atts->SetDim2MaxRange(atts->GetDim2MaxRange());
        }
    }

    // Do dim2NumBins
    if(which_widget == DataBinningAttributes::ID_dim2NumBins || doAll)
    {
        int val;
        if(LineEditGetInt(dim2NumBins, val))
            atts->SetDim2NumBins(val);
        else
        {
            ResettingError(tr("Number of bins"),
                IntToQString(atts->GetDim2NumBins()));
            atts->SetDim2NumBins(atts->GetDim2NumBins());
        }
    }

    // Do dim3MinRange
    if(which_widget == DataBinningAttributes::ID_dim3MinRange || doAll)
    {
        double val;
        if(LineEditGetDouble(dim3MinRange, val))
            atts->SetDim3MinRange(val);
        else
        {
            ResettingError(tr("Min"),
                DoubleToQString(atts->GetDim3MinRange()));
            atts->SetDim3MinRange(atts->GetDim3MinRange());
        }
    }

    // Do dim3MaxRange
    if(which_widget == DataBinningAttributes::ID_dim3MaxRange || doAll)
    {
        double val;
        if(LineEditGetDouble(dim3MaxRange, val))
            atts->SetDim3MaxRange(val);
        else
        {
            ResettingError(tr("Max"),
                DoubleToQString(atts->GetDim3MaxRange()));
            atts->SetDim3MaxRange(atts->GetDim3MaxRange());
        }
    }

    // Do dim3NumBins
    if(which_widget == DataBinningAttributes::ID_dim3NumBins || doAll)
    {
        int val;
        if(LineEditGetInt(dim3NumBins, val))
            atts->SetDim3NumBins(val);
        else
        {
            ResettingError(tr("Number of bins"),
                IntToQString(atts->GetDim3NumBins()));
            atts->SetDim3NumBins(atts->GetDim3NumBins());
        }
    }

    // Do emptyVal
    if(which_widget == DataBinningAttributes::ID_emptyVal || doAll)
    {
        double val;
        if(LineEditGetDouble(emptyVal, val))
            atts->SetEmptyVal(val);
        else
        {
            ResettingError(tr("Value for Bins With No Data"),
                DoubleToQString(atts->GetEmptyVal()));
            atts->SetEmptyVal(atts->GetEmptyVal());
        }
    }

}


//
// Qt Slot functions
//


void
QvisDataBinningWindow::numDimensionsChanged(int val)
{
    if(val != atts->GetNumDimensions())
    {
        atts->SetNumDimensions(DataBinningAttributes::NumDimensions(val));
        Apply();
    }
}


void
QvisDataBinningWindow::dim1VarChanged(const QString &varName)
{
    atts->SetDim1Var(varName.toStdString());
    SetUpdate(false);
    Apply();
}


void
QvisDataBinningWindow::dim1MinRangeProcessText()
{
    GetCurrentValues(DataBinningAttributes::ID_dim1MinRange);
    Apply();
}


void
QvisDataBinningWindow::dim1MaxRangeProcessText()
{
    GetCurrentValues(DataBinningAttributes::ID_dim1MaxRange);
    Apply();
}


void
QvisDataBinningWindow::dim1NumBinsProcessText()
{
    GetCurrentValues(DataBinningAttributes::ID_dim1NumBins);
    Apply();
}


void
QvisDataBinningWindow::dim2VarChanged(const QString &varName)
{
    atts->SetDim2Var(varName.toStdString());
    SetUpdate(false);
    Apply();
}


void
QvisDataBinningWindow::dim2MinRangeProcessText()
{
    GetCurrentValues(DataBinningAttributes::ID_dim2MinRange);
    Apply();
}


void
QvisDataBinningWindow::dim2MaxRangeProcessText()
{
    GetCurrentValues(DataBinningAttributes::ID_dim2MaxRange);
    Apply();
}


void
QvisDataBinningWindow::dim2NumBinsProcessText()
{
    GetCurrentValues(DataBinningAttributes::ID_dim2NumBins);
    Apply();
}


void
QvisDataBinningWindow::dim3VarChanged(const QString &varName)
{
    atts->SetDim3Var(varName.toStdString());
    SetUpdate(false);
    Apply();
}


void
QvisDataBinningWindow::dim3MinRangeProcessText()
{
    GetCurrentValues(DataBinningAttributes::ID_dim3MinRange);
    Apply();
}


void
QvisDataBinningWindow::dim3MaxRangeProcessText()
{
    GetCurrentValues(DataBinningAttributes::ID_dim3MaxRange);
    Apply();
}


void
QvisDataBinningWindow::dim3NumBinsProcessText()
{
    GetCurrentValues(DataBinningAttributes::ID_dim3NumBins);
    Apply();
}


void
QvisDataBinningWindow::dim1BinBasedOnChanged(int val)
{
    DataBinningAttributes::BinBasedOn newVal;
    if (val == 0)
        newVal = DataBinningAttributes::Variable;
    else if (val == 1)
        newVal = DataBinningAttributes::X;
    else if (val == 2)
        newVal = DataBinningAttributes::Y;
    else /*if (val == 3) */
        newVal = DataBinningAttributes::Z;
    if(newVal != atts->GetDim1BinBasedOn())
    {
        atts->SetDim1BinBasedOn(newVal);
        Apply();
    }
}

void
QvisDataBinningWindow::dim2BinBasedOnChanged(int val)
{
    DataBinningAttributes::BinBasedOn newVal;
    if (val == 0)
        newVal = DataBinningAttributes::Variable;
    else if (val == 1)
        newVal = DataBinningAttributes::X;
    else if (val == 2)
        newVal = DataBinningAttributes::Y;
    else /*if (val == 3) */
        newVal = DataBinningAttributes::Z;
    if(newVal != atts->GetDim2BinBasedOn())
    {
        atts->SetDim2BinBasedOn(newVal);
        Apply();
    }
}

void
QvisDataBinningWindow::dim3BinBasedOnChanged(int val)
{
    DataBinningAttributes::BinBasedOn newVal;
    if (val == 0)
        newVal = DataBinningAttributes::Variable;
    else if (val == 1)
        newVal = DataBinningAttributes::X;
    else if (val == 2)
        newVal = DataBinningAttributes::Y;
    else /*if (val == 3)*/
        newVal = DataBinningAttributes::Z;
    if(newVal != atts->GetDim3BinBasedOn())
    {
        atts->SetDim3BinBasedOn(newVal);
        Apply();
    }
}

void
QvisDataBinningWindow::outputChanged(int val)
{
    if(val != atts->GetOutputType())
    {
        atts->SetOutputType(DataBinningAttributes::OutputType(val));
        SetUpdate(false);
        Apply();
    }
}

void
QvisDataBinningWindow::outOfBoundsBehaviorChanged(int val)
{
    if(val != atts->GetOutOfBoundsBehavior())
    {
        atts->SetOutOfBoundsBehavior(DataBinningAttributes::OutOfBoundsBehavior(val));
        SetUpdate(false);
        Apply();
    }
}


void
QvisDataBinningWindow::reductionOperatorClicked(int val)
{
    if(val != atts->GetReductionOperator())
    {
        atts->SetReductionOperator(DataBinningAttributes::ReductionOperator(val));
        Apply();
    }
}


void
QvisDataBinningWindow::varForReductionChanged(const QString &varName)
{
    atts->SetVarForReduction(varName.toStdString());
    SetUpdate(false);
    Apply();
}


void
QvisDataBinningWindow::emptyValProcessText()
{
    GetCurrentValues(DataBinningAttributes::ID_emptyVal);
    Apply();
}


void
QvisDataBinningWindow::dim1SpecifyRangeToggled(bool v)
{
    atts->SetDim1SpecifyRange(v);
    Apply();
}

void
QvisDataBinningWindow::dim2SpecifyRangeToggled(bool v)
{
    atts->SetDim2SpecifyRange(v);
    Apply();
}

void
QvisDataBinningWindow::dim3SpecifyRangeToggled(bool v)
{
    atts->SetDim3SpecifyRange(v);
    Apply();
}


void
QvisDataBinningWindow::removeEmptyBinsToggled(bool v)
{
    atts->SetRemoveEmptyValFromCurve(v);
    Apply();
}
